home *** CD-ROM | disk | FTP | other *** search
- Subject: Re: CyberItems and FW_CWritable/ReadableStream
- Sent: 5/11/96 1:52 PM
- Received: 5/17/96 9:02 AM
- From: Mark Lanett, mlanett@meer.net
- Reply-To: ODF-Interest@CILabs.ORG
- To: OpenDoc Development Framework Discussion List, ODF-Interest@CILabs.
-
- >It's been noted that ODF 1.0 has Cyberdog support. I ran into a little
- >problem this evening with d11, and wonder if 1.0 has a good solution to
- >it...
-
- First off, the stuff in ODF R1 is pretty rudimentary. We'll be putting
- updates on our web site with bug fixes and lots more features. It'll be
- announced in a week or so (after WWDC).
-
- Second, regarding streaming in general: you don't want to go getting the
- StorageUnit from a sink. While today you are almost always dealing with a
- StorageUnitSink, which has a StorageUnit behind it, this won't always be
- the case. For instance, ODF R1 has a BufferSink which sits on top of
- StorageUnitSinks, and Real Soon Now you'll also be using a CyberStreamSink.
- If you must get the sink, at least use runtime dynamic casting.
-
- Thirdly, about streaming cyberitems:
-
- Actually CyberItem *does* have an unflatten method. This solves most
- problems, except that you need to instantiate a CyberItem before you can
- unflatten it, which means you need to know the classname. Fortunately the
- classname is part of the flattened cyberitem data. I'm not worried about
- the format changing -- since it has a version number, that can be dealt
- with.
-
- These routines work with R1, but you can probably use them under d11 with
- few or no problems.
-
- /*
- Utilities for getting CyberItems into and out of ODF streams.
-
- Format of a CyberItem:
-
- long length (includes this field)
- short signature ('cy')
- short version
- long classid length
- N classid
- <private data>
- */
-
- void FW_WriteCyberItem (Environment* ev, CyberItem* ci, FW_OSink* sink)
- {
- long size = ci->GetFlatSize(ev);
- TempODPtr tbuffer = new char[size];
- char* buffer = (char*) (void*) tbuffer;
- size = ci->Flatten (ev, buffer, size);
- sink->Write (ev, buffer, size);
- }
-
- CyberItem* FW_ReadCyberItem (Environment* ev, CyberSession* session,
- FW_OSink* sink)
- {
- // First we read in the classname to create the CyberItem
- FW_CReadableStream header (sink);
- long size, classsize;
- short signature, version;
- header >> size >> signature >> version >> classsize;
- if (signature != 'cy')
- FW_Failure (FW_xCorruptArchiveStream);
- TempODPtr tclassname = new char [classsize+1];
- char* classname = (char*) (void*) tclassname;
- header.Read (classname, classsize);
- classname[classsize] = 0;
-
- // Create a buffer with the CyberItem header and data
- TempODPtr tbuffer = new char[size];
- char* buffer = (char*) (void*) tbuffer;
- FW_PMemorySink copysink (ev, buffer, size, 0);
- FW_CWritableStream copy (copysink);
- copy << size << signature << version << classsize;
- copy.Write (classname, classsize);
- long offset = copysink->GetPosition(ev);
- sink->Read (ev, buffer + offset, size - offset);
-
- // Finally create the CyberItem and read it from the memory buffer.
- CyberItem* ci = session->NewCyberItem (ev, classname);
- FW_TRY
- ci->ICyberItem (ev);
- ci->Unflatten (ev, buffer);
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING() {
- delete ci;
- FW_THROW_SAME();
- }
- FW_CATCH_END
-
- return ci;
- }
-
-
- --
- Mark Lanett <mlanett@meer.net>
- Have a bajillion brilliant Jobsian lithium licks
-
-